<template>
  <div>
    <!--
          必备：
            action 上传地址必填，现在没有放个 # 即可
            file-list 管理文件

          样式
            list-tye 控制显示的样式，给个 picture-card
            :class 可以绑定动态类名，根据图片存在与否决定显示上传图片

          其他钩子：
            :on-preview  绑定后会出现放大镜，点击弹窗逻辑需要自己实现
            :on-remove   绑定后会出现删除的垃圾桶
            :on-change   绑定后，当文件发生改变立即触发
            :http-request  改变图片上传默认路径
       -->
    <el-upload
      :class="{disable:fileList.length>0}"
      action="#"
      :on-preview="onPreview"
      :on-remove="onRemove"
      :on-change="onChange"
      :before-upload="beforeUpload"
      :http-request="httpRequest"
      list-type="picture-card"
      :file-list="fileList"
    >
      <i class="el-icon-plus" />
    </el-upload>
    <el-progress
      v-show="isShowProgress"
      type="circle"
      :percentage="progress"
      status="success"
    />
    <el-dialog
      title="预览"
      :visible="isShowDiolog"
      @close="isShowDiolog=false"
    >
      <el-row
        type="flex"
        justify="center"
      >
        <img
          class="header"
          :src="imgURL"
          alt=""
        >
      </el-row>
    </el-dialog>
  </div>
</template>

<script>
// 使用插件，用于上传图片到腾讯云
import COS from 'cos-js-sdk-v5'
// 插件的内置构造函数
const cos = new COS({
  SecretId: 'AKIDqRmrfCSSBcmfIelbBUWHlytXx6ybx3sQ',
  SecretKey: 'IK5cstd6ICqDJ8gxxg9LGuHNCk12mFQL'
})
export default {
  data() {
    return {
      fileList: [], // 用于存放图片的路径
      imgURL: '', // 用于放在 img标签，展示图片在页面
      isShowDiolog: false, // 设置显示与隐藏弹窗
      progress: 0, // 用于进度条的进度
      isShowProgress: false // 用于是否展示进度条
    }
  },
  methods: {
    // ! 放大图片
    onPreview(file) {
      this.isShowDiolog = true
      this.imgURL = file.url
    },
    // ! 移除图片
    onRemove(file, fileList) {
      // 由于没有双向绑定数据，删除图片 this.fileList会遗留
      // 这个函数就把最新列表传进来，覆盖即可
      this.fileList = fileList
    },
    // ! 当上传文件改变事件触发的方法
    onChange(file, fileList) {
      this.fileList = fileList
    },
    // ! 上传前校验
    beforeUpload(file) {
      const fileSize = file.size
      const maxSize = 2 * 1024 * 1024
      // 判断用户上传的图片文件是否大于设定的字节
      if (fileSize > maxSize) {
        this.$message.warning('只能上传小于2M的图片')
        return false
      }
      // 设置白名单，用于判断用户上传的文件是否存在白名单中
      const whiteList = ['image/jpeg', 'image/png']
      if (!whiteList.includes(file.type)) {
        // 如果不在白名单中，则不执行下面的代码，return 返回
        this.$message.warning('暂时只支持 jpeg / png 格式图片')
        return false
      }
    },
    // ! 改变图片上传路径
    httpRequest(params) {
      this.isShowProgress = true //  关闭弹窗
      cos.putObject(
        {
          Bucket: 'test-21-12-1309020635' /* 存储桶的名称 必须 */,
          Region: 'ap-nanjing' /* 存储桶所在地域，必须字段 */,
          Key: params.file.name /* 存储在桶里面的对象键 必须 */,
          StorageClass: 'STANDARD',
          Body: params.file, // 上传文件对象
          onProgress: (progressData) => {
            // 用于设置进度条
            this.progress = (progressData.loaded / progressData.total) * 100
          }
        },
        (err, data) => {
          //  判断图片上传是否成功
          if (!err) {
            this.fileList[0].status = 'success'
            this.fileList[0].url = `http://${data.Location}`
          }
          this.isShowProgress = false
        }
      )
    }
  }
}
</script>

<style lang="scss" scoped>
.disable {
  ::v-deep .el-upload--picture-card {
    display: none;
  }
}
::v-deep .el-dialog__header {
  background-color: royalblue;
  span {
    color: #fff;
  }
  .el-dialog__close {
    color: #fff;
  }
}
.header {
  object-fit: contain;
}
</style>
